package cn.lin.handler;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lin.domain.Quick;
import cn.lin.domain.Sign;
import cn.lin.domain.SignUser;
import cn.lin.service.ClassRoomServiceYH;
import cn.lin.service.QuickService;
import cn.lin.service.SignService;
import cn.lin.util.KeyWords;
import cn.lin.vo.ChatMessage;
import cn.lin.vo.NotifyTeacherSignVO;
import cn.lin.vo.QuickVO;
import cn.lin.vo.SignInMsgVO;
import cn.lin.vo.SignUserVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author zxy
 * @date 2024/12/3 11:59
 */
@Component
@CrossOrigin(origins = "*")
@ServerEndpoint(value = "/channel")
public class EchoChannel {
    //当用户上线时,储存该用户的会话集合
    private final static Map<String, Session> sessions = new ConcurrentHashMap<>();

    private static ClassRoomServiceYH classRoomServiceYH;

    private static SignService signService;

   private static QuickService quickService;
   @Autowired
   private void setQuickService(QuickService quickService) {
        EchoChannel.quickService = quickService;
    }

    @Autowired
    private void setSignService(SignService signService) {
        EchoChannel.signService = signService;
    }

    @Autowired
    public void setClassRoomServiceYH(ClassRoomServiceYH classRoomServiceYH) {
        EchoChannel.classRoomServiceYH = classRoomServiceYH;
    }

    private static RedisTemplate<String, Object> redisTemplate;

    @Autowired
    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        EchoChannel.redisTemplate = redisTemplate;
    }

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("connect success");
        //将上线的用户添加到map中
        sessions.put(session.getId(), session);

        if (redisTemplate.hasKey("messageInfo")) {
            List<Object> info = redisTemplate.opsForList().range("messageInfo", 0, -1);
            ObjectMapper objectMapper = new ObjectMapper();
            String string = null;
            List<String> list = new ArrayList<>();
            for (Object o : info) {
                try {
                    string = objectMapper.writeValueAsString(o);
                    list.add(string);
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
            }
            try {
                for (String s : list) {
                    session.getBasicRemote().sendText(s);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * @author: zxy
     * @date: 2024/12/3 16:04
     * @param: 课堂内人发送的信息
     **/
    @OnMessage
    public void onMessage(String message) {
        System.out.println("message: " + message);
        ObjectMapper objectMapper = new ObjectMapper();
        // 签到信息
        String signMessage = null;

        String type = getType(message);

        switch (type) {
            // 聊天消息
            case KeyWords.CHAT_MESSAGE:
                ChatMessage chatMessage = null;
                try {
                    chatMessage = objectMapper.readValue(message, ChatMessage.class);
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
                redisTemplate.opsForList().rightPush("messageInfo", chatMessage);
                break;

            // 签到信息标识
            case KeyWords.SIGN_IN_SYNC:
                try {
                    SignInMsgVO sign = objectMapper.readValue(message, SignInMsgVO.class);

                    List<SignUser> signUserList = signService.initiateSignIn(sign.getData());
                    if (signUserList != null) {
                        // 创建一个新的消息对象，包含原始数据和新的 signUserList
                        sign.setSignUserList(signUserList);
                        // 将新消息转换为 JSON 字符串
                        signMessage = objectMapper.writeValueAsString(sign);
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                break;

            // 学生签到信息标识
            case KeyWords.STUDENT_SIGN_IN:
                try {
                    SignUserVO stuSign = objectMapper.readValue(message, SignUserVO.class);

                    int updateRet = signService.updateSignInStu(stuSign.getData());

                    if (updateRet != 0) {
                        NotifyTeacherSignVO notifyTeacherSignVO = new NotifyTeacherSignVO();
                        notifyTeacherSignVO.setType(KeyWords.TEACHER_SIGN_IN);
                        notifyTeacherSignVO.setSignUserId(stuSign.getData().getUserId());

                        message = objectMapper.writeValueAsString(notifyTeacherSignVO);
                    }
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
                break;
            //发起抢答标识
            case KeyWords.QUICK_MESSAGE:

                QuickVO quickVO = null;
                try {
                    quickVO = objectMapper.readValue(message, QuickVO.class);
                    System.out.println("quickVO: " + quickVO);
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
                Quick quick = quickVO.getData();
                //将抢答信息存储在表中
                quickService.addQuick(quick);
                quick = quickService.findID(quick.getQuickName());
                //将抢答数量存储在redis中
                redisTemplate.opsForValue().set("quick:" + quick.getId(), quick.getQuickNum(), 5, TimeUnit.MINUTES);
                break;
        }

        if (signMessage != null) {
            // 签到更新消息
            message = signMessage;
        }
        // remind -> 默认执行方法 且 所有方法都会执行!!
        for (Map.Entry<String, Session> entry : sessions.entrySet()) {
            try {
                entry.getValue().getBasicRemote().sendText(message);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("connect close");
        sessions.remove(session.getId());
    }

    @OnError
    public void onError(Throwable error) {
        System.out.println(error);
    }

    public String getType(String message) {
        JSONObject jsonObject = JSONUtil.parseObj(message);
        if (!jsonObject.containsKey("type")) {
            System.out.println("JSON does not contain 'type' field");
        }
        return jsonObject.getStr("type");
    }


}
